/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.solr.handler.admin;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.util.IOUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.UpdateParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.*;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.RefCounted;
import org.apache.solr.util.SolrPluginUtils;
import org.apache.solr.update.MergeIndexesCommand;
import org.apache.solr.update.UpdateHandler;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;

/**
 * @version $Id: CoreAdminHandler.java 1171306 2011-09-15 22:43:33Z janhoy $
 * @since solr 1.3
 */

public class CoreAdminHandler{
	
}
//
//public class CoreAdminHandler extends RequestHandlerBase {
//  protected static Logger log = LoggerFactory.getLogger(CoreAdminHandler.class);
//  protected final CoreContainer coreContainer;
//
//  public CoreAdminHandler() {
//    super();
//    // Unlike most request handlers, CoreContainer initialization 
//    // should happen in the constructor...  
//    this.coreContainer = null;
//  }
//
//
//  /**
//   * Overloaded ctor to inject CoreContainer into the handler.
//   *
//   * @param coreContainer Core Container of the solr webapp installed.
//   */
//  public CoreAdminHandler(final CoreContainer coreContainer) {
//    this.coreContainer = coreContainer;
//  }
//
//
//  @Override
//  final public void init(NamedList args) {
//    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
//            "CoreAdminHandler should not be configured in solrconf.xml\n" +
//                    "it is a special Handler configured directly by the RequestDispatcher");
//  }
//
//  /**
//   * The instance of CoreContainer this handler handles. This should be the CoreContainer instance that created this
//   * handler.
//   *
//   * @return a CoreContainer instance
//   */
//  public CoreContainer getCoreContainer() {
//    return this.coreContainer;
//  }
//
//  @Override
//  public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
//    // Make sure the cores is enabled
//    CoreContainer cores = getCoreContainer();
//    if (cores == null) {
//      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
//              "Core container instance missing");
//    }
//    boolean doPersist = false;
//
//    // Pick the action
//    SolrParams params = req.getParams();
//    CoreAdminAction action = CoreAdminAction.STATUS;
//    String a = params.get(CoreAdminParams.ACTION);
//    if (a != null) {
//      action = CoreAdminAction.get(a);
//      if (action == null) {
//        doPersist = this.handleCustomAction(req, rsp);
//      }
//    }
//    if (action != null) {
//      switch (action) {
//        case CREATE: {
//          doPersist = this.handleCreateAction(req, rsp);
//          break;
//        }
//
//        case RENAME: {
//          doPersist = this.handleRenameAction(req, rsp);
//          break;
//        }
//
//        case ALIAS: {
//          throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'ALIAS' is not supported " +
//            req.getParams().get(CoreAdminParams.ACTION));
//        }
//
//        case UNLOAD: {
//          doPersist = this.handleUnloadAction(req, rsp);
//          break;
//        }
//
//        case STATUS: {
//          doPersist = this.handleStatusAction(req, rsp);
//          break;
//
//        }
//
//        case PERSIST: {
//          doPersist = this.handlePersistAction(req, rsp);
//          break;
//        }
//
//        case RELOAD: {
//          doPersist = this.handleReloadAction(req, rsp);
//          break;
//        }
//
//        case SWAP: {
//          doPersist = this.handleSwapAction(req, rsp);
//          break;
//        }
//
//        case MERGEINDEXES: {
//          doPersist = this.handleMergeAction(req, rsp);
//          break;
//        }
//
//        default: {
//          doPersist = this.handleCustomAction(req, rsp);
//          break;
//        }
//        case LOAD:
//          break;
//      }
//    }
//    // Should we persist the changes?
//    if (doPersist) {
//      cores.persist();
//      rsp.add("saved", cores.getConfigFile().getAbsolutePath());
//    }
//    rsp.setHttpCaching(false);
//  }
//
//  protected boolean handleMergeAction(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException {
//    SolrParams params = req.getParams();
//    String cname = params.required().get(CoreAdminParams.CORE);
//    SolrCore core = coreContainer.getCore(cname);
//
//    SolrCore[] sourceCores = null;
//    RefCounted<SolrIndexSearcher>[] searchers = null;
//    // stores readers created from indexDir param values
//    IndexReader[] readersToBeClosed = null;
//    if (core != null) {
//      try {
//        String[] dirNames = params.getParams(CoreAdminParams.INDEX_DIR);
//        if (dirNames == null || dirNames.length == 0) {
//          String[] sources = params.getParams("srcCore");
//          if (sources == null || sources.length == 0)
//            throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
//                "At least one indexDir or srcCore must be specified");
//
//          sourceCores = new SolrCore[sources.length];
//          for (int i = 0; i < sources.length; i++) {
//            String source = sources[i];
//            SolrCore srcCore = coreContainer.getCore(source);
//            if (srcCore == null)
//              throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
//                  "Core: " + source + " does not exist");
//            sourceCores[i] = srcCore;
//          }
//        } else  {
//          readersToBeClosed = new IndexReader[dirNames.length];
//          DirectoryFactory dirFactory = core.getDirectoryFactory();
//          for (int i = 0; i < dirNames.length; i++) {
//            readersToBeClosed[i] = IndexReader.open(dirFactory.open(dirNames[i]), true);
//          }
//        }
//
//        IndexReader[] readers = null;
//        if (readersToBeClosed != null)  {
//          readers = readersToBeClosed;
//        } else {
//          readers = new IndexReader[sourceCores.length];
//          searchers = new RefCounted[sourceCores.length];
//          for (int i = 0; i < sourceCores.length; i++) {
//            SolrCore solrCore = sourceCores[i];
//            // record the searchers so that we can decref
//            searchers[i] = solrCore.getSearcher(UpdateHandler.UPDATEPARTION,false,false);
//            readers[i] = searchers[i].get().getIndexReader();
//          }
//        }
//
//        UpdateRequestProcessorChain processorChain =
//                core.getUpdateProcessingChain(SolrPluginUtils.resolveUpdateChainParam(params, log));
//        SolrQueryRequest wrappedReq = new LocalSolrQueryRequest(core, req.getParams());
//        UpdateRequestProcessor processor =
//                processorChain.createProcessor(wrappedReq, rsp);
//
//        processor.processMergeIndexes(new MergeIndexesCommand(readers));
//      } finally {
//        if (searchers != null) {
//          for (RefCounted<SolrIndexSearcher> searcher : searchers) {
//            if (searcher != null) searcher.decref();
//          }
//        }
//        if (sourceCores != null) {
//          for (SolrCore solrCore : sourceCores) {
//            if (solrCore != null) solrCore.close();
//          }
//        }
//        if (readersToBeClosed != null) IOUtils.closeWhileHandlingException(readersToBeClosed);
//        core.close();
//      }
//    }
//    return coreContainer.isPersistent();
//  }
//
//  /**
//   * Handle Custom Action.
//   * <p/>
//   * This method could be overridden by derived classes to handle custom actions. <br> By default - this method throws a
//   * solr exception. Derived classes are free to write their derivation if necessary.
//   */
//  protected boolean handleCustomAction(SolrQueryRequest req, SolrQueryResponse rsp) {
//    throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unsupported operation: " +
//            req.getParams().get(CoreAdminParams.ACTION));
//  }
//
//  /**
//   * Handle 'CREATE' action.
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   *
//   * @throws SolrException in case of a configuration error.
//   */
//  protected boolean handleCreateAction(SolrQueryRequest req, SolrQueryResponse rsp) throws SolrException {
//    try {
//      SolrParams params = req.getParams();
//      String name = params.get(CoreAdminParams.NAME);
//      CoreDescriptor dcore = new CoreDescriptor(coreContainer, name, params.get(CoreAdminParams.INSTANCE_DIR));
//
//      //  fillup optional parameters
//      String opts = params.get(CoreAdminParams.CONFIG);
//      if (opts != null)
//        dcore.setConfigName(opts);
//
//      opts = params.get(CoreAdminParams.SCHEMA);
//      if (opts != null)
//        dcore.setSchemaName(opts);
//
//      opts = params.get(CoreAdminParams.DATA_DIR);
//      if (opts != null)
//        dcore.setDataDir(opts);
//
//      // Process all property.name=value parameters and set them as name=value core properties
//      Properties coreProperties = new Properties();
//      Iterator<String> parameterNamesIterator = params.getParameterNamesIterator();
//      while (parameterNamesIterator.hasNext()) {
//          String parameterName = parameterNamesIterator.next();
//          if(parameterName.startsWith(CoreAdminParams.PROPERTY_PREFIX)) {
//              String parameterValue = params.get(parameterName);
//              String propertyName = parameterName.substring(CoreAdminParams.PROPERTY_PREFIX.length()); // skip prefix
//              coreProperties.put(propertyName, parameterValue);
//          }
//      }
//      dcore.setCoreProperties(coreProperties);
//      
//      SolrCore core = coreContainer.create(dcore);
//      coreContainer.register(name, core, false);
//      rsp.add("core", core.getName());
//      return coreContainer.isPersistent();
//    } catch (Exception ex) {
//      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
//              "Error executing default implementation of CREATE", ex);
//    }
//  }
//
//  /**
//   * Handle "RENAME" Action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   *
//   * @throws SolrException
//   */
//  protected boolean handleRenameAction(SolrQueryRequest req, SolrQueryResponse rsp) throws SolrException {
//    SolrParams params = req.getParams();
//
//    String name = params.get(CoreAdminParams.OTHER);
//    String cname = params.get(CoreAdminParams.CORE);
//    boolean doPersist = false;
//
//    if (cname.equals(name)) return doPersist;
//
//    SolrCore core = coreContainer.getCore(cname);
//    if (core != null) {
//      doPersist = coreContainer.isPersistent();
//      coreContainer.register(name, core, false);
//      coreContainer.remove(cname);
//      core.close();
//    }
//    return doPersist;
//  }
//
//  /**
//   * Handle "ALIAS" action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   */
//  @Deprecated
//  protected boolean handleAliasAction(SolrQueryRequest req, SolrQueryResponse rsp) {
//    SolrParams params = req.getParams();
//
//    String name = params.get(CoreAdminParams.OTHER);
//    String cname = params.get(CoreAdminParams.CORE);
//    boolean doPersist = false;
//    if (cname.equals(name)) return doPersist;
//
//    SolrCore core = coreContainer.getCore(cname);
//    if (core != null) {
//      doPersist = coreContainer.isPersistent();
//      coreContainer.register(name, core, false);
//      // no core.close() since each entry in the cores map should increase the ref
//    }
//    return doPersist;
//  }
//
//
//  /**
//   * Handle "UNLOAD" Action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   */
//  protected boolean handleUnloadAction(SolrQueryRequest req, SolrQueryResponse rsp) throws SolrException {
//    SolrParams params = req.getParams();
//    String cname = params.get(CoreAdminParams.CORE);
//    SolrCore core = coreContainer.remove(cname);
//    if(core == null){
//       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
//              "No such core exists '"+cname+"'");
//    }
//    if (params.getBool(CoreAdminParams.DELETE_INDEX, false)) {
//      core.addCloseHook(new CloseHook() {
//        @Override
//        public void preClose(SolrCore core) {}
//
//        @Override
//        public void postClose(SolrCore core) {
//          File dataDir = new File(core.getIndexDir(UpdateHandler.UPDATEPARTION));
//          for (File file : dataDir.listFiles()) {
//            if (!file.delete()) {
//              log.error(file.getAbsolutePath() + " could not be deleted on core unload");
//            }
//          }
//          if (!dataDir.delete()) log.error(dataDir.getAbsolutePath() + " could not be deleted on core unload");
//        }
//      });
//    }
//    core.close();
//    return coreContainer.isPersistent();
//
//  }
//
//  /**
//   * Handle "STATUS" action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   */
//  protected boolean handleStatusAction(SolrQueryRequest req, SolrQueryResponse rsp)
//          throws SolrException {
//    SolrParams params = req.getParams();
//
//    String cname = params.get(CoreAdminParams.CORE);
//    boolean doPersist = false;
//    NamedList<Object> status = new SimpleOrderedMap<Object>();
//    try {
//      if (cname == null) {
//        for (String name : coreContainer.getCoreNames()) {
//          status.add(name, getCoreStatus(coreContainer, name));
//        }
//      } else {
//        status.add(cname, getCoreStatus(coreContainer, cname));
//      }
//      rsp.add("status", status);
//      doPersist = false; // no state change
//      return doPersist;
//    } catch (Exception ex) {
//      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
//              "Error handling 'status' action ", ex);
//    }
//  }
//
//  /**
//   * Handler "PERSIST" action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   *
//   * @throws SolrException
//   */
//  protected boolean handlePersistAction(SolrQueryRequest req, SolrQueryResponse rsp)
//          throws SolrException {
//    SolrParams params = req.getParams();
//    boolean doPersist = false;
//    String fileName = params.get(CoreAdminParams.FILE);
//    if (fileName != null) {
//      File file = new File(coreContainer.getConfigFile().getParentFile(), fileName);
//      coreContainer.persistFile(file);
//      rsp.add("saved", file.getAbsolutePath());
//      doPersist = false;
//    } else if (!coreContainer.isPersistent()) {
//      throw new SolrException(SolrException.ErrorCode.FORBIDDEN, "Persistence is not enabled");
//    } else
//      doPersist = true;
//
//    return doPersist;
//  }
//
//  /**
//   * Handler "RELOAD" action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   */
//  protected boolean handleReloadAction(SolrQueryRequest req, SolrQueryResponse rsp) {
//    SolrParams params = req.getParams();
//    String cname = params.get(CoreAdminParams.CORE);
//    try {
//      coreContainer.reload(cname);
//      return false; // no change on reload
//    } catch (Exception ex) {
//      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error handling 'reload' action", ex);
//    }
//  }
//
//  /**
//   * Handle "SWAP" action
//   *
//   * @param req
//   * @param rsp
//   *
//   * @return true if a modification has resulted that requires persistance 
//   *         of the CoreContainer configuration.
//   */
//  protected boolean handleSwapAction(SolrQueryRequest req, SolrQueryResponse rsp) {
//    final SolrParams params = req.getParams();
//    final SolrParams required = params.required();
//
//    final String cname = params.get(CoreAdminParams.CORE);
//    boolean doPersist = params.getBool(CoreAdminParams.PERSISTENT, coreContainer.isPersistent());
//    String other = required.get(CoreAdminParams.OTHER);
//    coreContainer.swap(cname, other);
//    return doPersist;
//
//  }
//
//  protected NamedList<Object> getCoreStatus(CoreContainer cores, String cname) throws IOException {
//    NamedList<Object> info = new SimpleOrderedMap<Object>();
//    SolrCore core = cores.getCore(cname);
//    if (core != null) {
//      try {
//        info.add("name", core.getName());
//        info.add("instanceDir", normalizePath(core.getResourceLoader().getInstanceDir()));
//        info.add("dataDir", normalizePath(core.getDataDir()));
//        info.add("startTime", new Date(core.getStartTime()));
//        info.add("uptime", System.currentTimeMillis() - core.getStartTime());
//        RefCounted<SolrIndexSearcher> searcher = core.getSearcher(UpdateHandler.UPDATEPARTION,false,false);
//        try {
//          info.add("index", LukeRequestHandler.getIndexInfo(searcher.get().getReader(), false));
//        } finally {
//          searcher.decref();
//        }
//      } finally {
//        core.close();
//      }
//    }
//    return info;
//  }
//
//  protected static String normalizePath(String path) {
//    if (path == null)
//      return null;
//    path = path.replace('/', File.separatorChar);
//    path = path.replace('\\', File.separatorChar);
//    return path;
//  }
//
//
//  //////////////////////// SolrInfoMBeans methods //////////////////////
//
//  @Override
//  public String getDescription() {
//    return "Manage Multiple Solr Cores";
//  }
//
//  @Override
//  public String getVersion() {
//    return "$Revision: 1171306 $";
//  }
//
//  @Override
//  public String getSourceId() {
//    return "$Id: CoreAdminHandler.java 1171306 2011-09-15 22:43:33Z janhoy $";
//  }
//
//  @Override
//  public String getSource() {
//    return "$URL: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene_solr_3_5/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java $";
//  }
//}
